/*
 * EasyBounceRankList.cpp
 *
 *  Created on: 2009-3-14
 *      Author: Wayne
 */

// INCLUDE FILES
#include <f32file.h>
#include <utf.h>

#include "EasyBounceRankList.h"

LOCAL_D RFs rFs;

const int KMaxRankLength = 10;
const int KMaxFileSize = 500;

_LIT( KFileName, "c:\\ebrank.txt");
_LIT( KFormatString, "%d\t%S\t%d");

// -----------------------------------------------------------------------------
// CEasyBounceRankList::NewL
// -----------------------------------------------------------------------------
//
CEasyBounceRankList* CEasyBounceRankList::NewL()
    {
    CEasyBounceRankList *self = CEasyBounceRankList::NewLC();
    CleanupStack::Pop(self);
    
    return self;
    }

// -----------------------------------------------------------------------------
// CEasyBounceRankList::NewLC()
// -----------------------------------------------------------------------------
//
CEasyBounceRankList* CEasyBounceRankList::NewLC()
    {
    CEasyBounceRankList *self = new (ELeave) CEasyBounceRankList();
    CleanupStack::PushL(self);
    self->ConstructL();
    
    return self;
    }

// -----------------------------------------------------------------------------
// CEasyBounceRankList::~CEasyBounceRankList()
// -----------------------------------------------------------------------------
//
CEasyBounceRankList::~CEasyBounceRankList()
    {
    rFs.Close();
    
    iName.ResetAndDestroy();
    iScore.Reset();
    }

// -----------------------------------------------------------------------------
// CEasyBounceRankList::CEasyBounceRankList()
// -----------------------------------------------------------------------------
//
CEasyBounceRankList::CEasyBounceRankList()
    {
    // initialise local data
    }

// -----------------------------------------------------------------------------
// CEasyBounceRankList::ConstructL() 
// -----------------------------------------------------------------------------
//
void CEasyBounceRankList::ConstructL() 
    {
    LoadRankDataL();
    }

// -----------------------------------------------------------------------------
// 
// -----------------------------------------------------------------------------
//
void CEasyBounceRankList::LoadRankDataL()
	{
	User::LeaveIfError( rFs.Connect() );
	TFileName vFileName;
	vFileName.Append( KFileName );

	TBuf<20> temp;
	RFile file;

	if ( KErrNone != file.Open( rFs, vFileName, EFileWrite | EFileShareAny ) )
		{
	    User::Leave( KErrAccessDenied );
		}

	TInt size;
	User::LeaveIfError( file.Size( size ) );
	HBufC8 *buf8 = HBufC8::NewLC( size );
	TPtr8 ptr8 = buf8->Des();
	User::LeaveIfError( file.Read( ptr8 ) );
	HBufC *buf16 = HBufC::NewMaxLC( 3 * ptr8.Length() );
	TPtr16 ptr16 = buf16->Des();
	CnvUtfConverter::ConvertToUnicodeFromUtf8( ptr16, ptr8);

	TInt i, score;
	TBuf<50> tempbuf;
	iName.Reset();
	iScore.Reset();
	for (i = 0; i < ptr16.Length(); i++)
	    {
	    TUint16 onebuf = ptr16[i];
	    if (onebuf == '\n')
	        {
	        TLex lex(tempbuf);
	        lex.Val(score);
	        iScore.Append(score);
	        tempbuf.Zero();
	        }
	    else if (onebuf == '\t')
	        {
	        iName.Append(tempbuf.AllocL());
	        tempbuf.Zero();
	        }
	    else
	        {
	        tempbuf.Append(onebuf);
	        }
	    }
	    CleanupStack::PopAndDestroy();
	    CleanupStack::PopAndDestroy();
	    file.Close();
	}

// -----------------------------------------------------------------------------
// 
// -----------------------------------------------------------------------------
//
TInt CEasyBounceRankList::InsertPosition( TInt aScore )
	{
	TInt position = KMaxRankLength + 1 ;
	
	if ( iScore.Count() < KMaxRankLength )
		{
		return iScore.Count();
		}
	
	for ( TInt i = 0; i < KMaxRankLength; ++i )
		{
		if ( aScore > iScore[i] )
			{
			position = i;
			break;
			}
		}
		
	return position;
	}

// -----------------------------------------------------------------------------
// 
// -----------------------------------------------------------------------------
//
void CEasyBounceRankList::GetRankDataL( CDesCArray* aArray )
    {
    aArray->Reset();
    
    for ( TInt i = 0; i < iScore.Count(); i++ )
        {
        TBuf<20> name;
        TInt score;
            
        name = iName[i]->Des();
        score = iScore[i];
            
        TBuf<50> item;
        item.Format( KFormatString, i+1, &name, score);
            
        aArray->AppendL(item);
        }
    }

// -----------------------------------------------------------------------------
// 
// -----------------------------------------------------------------------------
//
TBool CEasyBounceRankList::SetNewRecord( TInt aScore )
    {
    TBool isReadyToAdd;
    
    TInt position = InsertPosition( aScore );
    if ( position > KMaxRankLength )
        {
        isReadyToAdd = EFalse;
        }
    else
        {
        // Add score to list
        iScore.Insert( aScore, position );
        iPos = position;
        isReadyToAdd = ETrue;
        }
    
    return isReadyToAdd;
    }

// -----------------------------------------------------------------------------
// 
// -----------------------------------------------------------------------------
//
TInt CEasyBounceRankList::SetName( const TDesC& aName )
    {
    // Score list is updated
    // Now we have to insert name to name list
    iName.Insert( aName.AllocL(), iPos );
    
    // OK, let's save the new list to file
    TInt i, temp;
    TInt filesize = KMaxFileSize;
    TInt usersort = KMaxRankLength;
    usersort = usersort > iScore.Count() ? iScore.Count(): usersort;
    RFile file;
    TFileName vFileName;
    vFileName.Append( KFileName );
    User::LeaveIfError(rFs.Connect());
    if (KErrNone == file.Open( rFs, vFileName, EFileWrite | EFileShareAny) )
        {
        file.Close();
        rFs.Delete( vFileName );
        }
    User::LeaveIfError( file.Create( rFs, vFileName, EFileWrite | EFileShareAny));

    HBufC *buf16 = HBufC::NewLC( filesize );
    TPtr16 ptr16 = buf16->Des();
    TBuf < 20 > tempbuf;
    for (i = 0; i < usersort; i++)
        {
        ptr16.Append( iName[i]->Des() );
        ptr16.Append( _L("\t") );
        temp = iScore[i];
        tempbuf.Format( _L("%d"), temp );
        ptr16.Append(tempbuf);
        ptr16.Append( _L("\n") );
        }

    HBufC8 *buf8 = HBufC8::NewLC( 2 * filesize );
    TPtr8 ptr8 = buf8->Des();

    CnvUtfConverter::ConvertFromUnicodeToUtf8( ptr8, ptr16 );
    file.SetSize( 0 );
    User::LeaveIfError( file.Write( ptr8 ) );
    file.Close();
    CleanupStack::PopAndDestroy();
    CleanupStack::PopAndDestroy();
    }

// End of File
